Create a new Console Application named AutoLotCUIClient. After you create your new project, be sure to add a reference to your AutoLotDAL.dll assembly, as well as System.Configuration.dll. Next, add the following using statements to your C# code file:
using AutoLotConnectedLayer; using System.Configuration; using System.Data;
Now insert a new App.config file into your project that contains a <connectionStrings> element, which you will use to connect to your instance of the AutoLot database, as in this example:
<configuration> <connectionStrings> <add name ="AutoLotSqlProvider" connectionString = "Data Source=(local)\SQLEXPRESS; Integrated Security=SSPI;Initial Catalog=AutoLot"/> </connectionStrings> </configuration>
The Main() method is responsible for prompting the user for a specific course of action and executing that request using a switch statement. This program allows the user to enter the following commands:
Each possible option is handled by a unique static method within the Program class. The next snippet shows the complete implementation of Main(). Notice that each method invoked from the do/while loop (with the exception of the ShowInstructions() method) takes an InventoryDAL object as its sole parameter:
static void Main(string[] args) { Console.WriteLine("***** The AutoLot Console UI *****\n"); // Get connection string from App.config. string cnStr = ConfigurationManager.ConnectionStrings["AutoLotSqlProvider"].ConnectionString; bool userDone = false; string userCommand = ""; // Create our InventoryDAL object. InventoryDAL invDAL = new InventoryDAL(); invDAL.OpenConnection(cnStr); // Keep asking for input until user presses the Q key. try { ShowInstructions(); do { Console.Write("\nPlease enter your command: "); userCommand = Console.ReadLine(); Console.WriteLine(); switch (userCommand.ToUpper()) { case "I": InsertNewCar(invDAL); break; case "U": UpdateCarPetName(invDAL); break; case "D": DeleteCar(invDAL); break; case "L": ListInventory(invDAL); break; case "S": ShowInstructions(); break; case "P": LookUpPetName(invDAL); break; case "Q": userDone = true; break; default: Console.WriteLine("Bad data! Try again"); break; } } while (!userDone); } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { invDAL.CloseConnection(); } }
The ShowInstructions() method does what you would expect:
private static void ShowInstructions() { Console.WriteLine("I: Inserts a new car."); Console.WriteLine("U: Updates an existing car."); Console.WriteLine("D: Deletes an existing car."); Console.WriteLine("L: Lists current inventory."); Console.WriteLine("S: Shows these instructions."); Console.WriteLine("P: Looks up pet name."); Console.WriteLine("Q: Quits program."); }
You could implement the ListInventory() method in either of two ways, based on how you constructed your data access library. Recall that the GetAllInventoryAsDataTable() method of InventoryDAL returns a DataTable object. You could implement this approach like this:
private static void ListInventory(InventoryDAL invDAL) { // Get the list of inventory. DataTable dt = invDAL.GetAllInventoryAsDataTable(); // Pass DataTable to helper function to display. DisplayTable(dt); }
The DisplayTable() helper method displays the table data using the Rows and Columns properties of the incoming DataTable (again, you will learn the full details of the DataTable object the next chapter, so don’t fret over the details):
private static void DisplayTable(DataTable dt) { // Print out the column names. for (int curCol = 0; curCol < dt.Columns.Count; curCol++) { Console.Write(dt.Columns[curCol].ColumnName + "\t"); } Console.WriteLine("\n----------------------------------"); // Print the DataTable. for (int curRow = 0; curRow < dt.Rows.Count; curRow++) { for (int curCol = 0; curCol < dt.Columns.Count; curCol++) { Console.Write(dt.Rows[curRow][curCol].ToString() + "\t"); } Console.WriteLine(); } }
If you would prefer to call the GetAllInventoryAsList() method of InventoryDAL, you could implement a method named ListInventoryViaList():
private static void ListInventoryViaList(InventoryDAL invDAL) { // Get the list of inventory. List<NewCar> record = invDAL.GetAllInventoryAsList(); foreach (NewCar c in record) { Console.WriteLine("CarID: {0}, Make: {1}, Color: {2}, PetName: {3}", c.CarID, c.Make, c.Color, c.PetName); } }
Deleting an existing automobile is as simple as asking the user for the ID of the car and passing this to the DeleteCar() method of the InventoryDAL type:
private static void DeleteCar(InventoryDAL invDAL) { // Get ID of car to delete. Console.Write("Enter ID of Car to delete: "); int id = int.Parse(Console.ReadLine()); // Just in case you have a referential integrity // violation! try { invDAL.DeleteCar(id); } catch(Exception ex) { Console.WriteLine(ex.Message); } }
Inserting a new record into the Inventory table is a simple matter of asking the user for the new bits of data (using Console.ReadLine() calls) and passing this data into the InsertAuto() method of InventoryDAL:
private static void InsertNewCar(InventoryDAL invDAL) { // First get the user data. int newCarID; string newCarColor, newCarMake, newCarPetName; Console.Write("Enter Car ID: "); newCarID = int.Parse(Console.ReadLine()); Console.Write("Enter Car Color: "); newCarColor = Console.ReadLine(); Console.Write("Enter Car Make: "); newCarMake = Console.ReadLine(); Console.Write("Enter Pet Name: "); newCarPetName = Console.ReadLine(); // Now pass to data access library. invDAL.InsertAuto(newCarID, newCarColor, newCarMake, newCarPetName); }
Recall that you overloaded InsertAuto() to take a NewCar object, rather than a set of independent arguments. Thus, you could have implemented InsertNewCar() like this:
private static void InsertNewCar(InventoryDAL invDAL) { // First get the user data. ... // Now pass to data access library. NewCar c = new NewCar { CarID = newCarID, Color = newCarColor, Make = newCarMake, PetName = newCarPetName }; invDAL.InsertAuto(c); }
The implementation of UpdateCarPetName() looks similar:
private static void UpdateCarPetName(InventoryDAL invDAL) { // First get the user data. int carID; string newCarPetName; Console.Write("Enter Car ID: "); carID = int.Parse(Console.ReadLine()); Console.Write("Enter New Pet Name: "); newCarPetName = Console.ReadLine(); // Now pass to data access library. invDAL.UpdateCarPetName(carID, newCarPetName); }
Obtaining the pet name of a given automobile works similarly to the previous methods; this is so because the data access library encapsulates all of the lower-level ADO.NET calls:
private static void LookUpPetName(InventoryDAL invDAL) { // Get ID of car to look up. Console.Write("Enter ID of Car to look up: "); int id = int.Parse(Console.ReadLine()); Console.WriteLine("Petname of {0} is {1}.", id, invDAL.LookUpPetName(id)); }
With this, your console-based front end is finished! It’s time to run your program and test each method. Here is some partial output that tests the L, P, and Q commands:
***** The AutoLot Console UI ***** I: Inserts a new car. U: Updates an existing car. D: Deletes an existing car. L: Lists current inventory. S: Shows these instructions. P: Looks up pet name. Q: Quits program. Please enter your command: L CarID Make Color PetName ---------------------------------- 83 Ford Rust Rusty 107 Ford Red Snake 678 Yugo Green Clunker 904 VW Black Hank 1000 BMW Black Bimmer 1001 BMW Tan Daisy 1992 Saab Pink Pinkey Please enter your command: P Enter ID of Car to look up: 904 Petname of 904 is Hank. Please enter your command: Q Press any key to continue . . .
Source Code You can find the AutoLotCUIClient application under the Chapter 21 subdirectory.